#include "nlohmann/json.hpp"
#include <arpa/inet.h>
#include <condition_variable>
#include <cstring>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#include <unistd.h>
#include <vector>

using json = nlohmann::json;

// 消息头结构
#pragma pack(push, 1)
struct MessageHeader {
  uint16_t magic;     // 魔法数
  uint16_t cmd;       // 命令类型
  uint32_t seq;       // 序列号
  uint32_t body_size; // 消息体大小
};
#pragma pack(pop)

// 消息结构
struct Message {
  MessageHeader header;
  std::vector<char> body;
};

// 消息处理函数
void process_message(const Message &msg, int client_fd) {
  std::cout << "服务器端接收到信息: cmd=" << msg.header.cmd
            << ", body_size=" << msg.header.body_size << std::endl;

  // 根据cmd类型处理消息
  switch (msg.header.cmd) {
  case 20002: // kNetCmdNewOrder
    std::cout << "Processing New Order" << std::endl;
    break;
  case 20004: // kNetCmdCancelOrder
    std::cout << "Processing Cancel Order" << std::endl;
    break;
  case 20016: // kNetCmdCancelAll
    std::cout << "Processing Cancel All Orders" << std::endl;
    break;
  case 20010: // kNetCmdMakeInternalTrade
    std::cout << "Processing Internal Trade" << std::endl;
    break;
  default:
    std::cout << "Unknown command: " << msg.header.cmd << std::endl;
    break;
  }

  // 模拟处理延迟
  std::this_thread::sleep_for(std::chrono::milliseconds(100));

  // 发送确认消息回客户端
  json response;
  response["status"] = "success";
  response["message"] = "Request processed successfully";

  std::string response_str = response.dump();
  const char *response_data = response_str.c_str();
  size_t response_size = response_str.size();

  // 构造响应消息头
  MessageHeader response_header;
  response_header.magic = htons(8888); // 魔法数
  response_header.cmd = htons(10001);  // 响应命令类型
  response_header.seq = htonl(0);      // 序列号
  response_header.body_size = htonl(static_cast<uint32_t>(response_size));

  // 发送响应消息头和消息体
  send(client_fd, &response_header, sizeof(response_header), 0);
  send(client_fd, response_data, response_size, 0);
}

// 消息解析函数
Message parse_message(const char *data, size_t size) {
  Message msg;
  memcpy(&msg.header, data, sizeof(MessageHeader));

  // 转换网络字节顺序到主机字节顺序
  msg.header.magic = ntohs(msg.header.magic);
  msg.header.cmd = ntohs(msg.header.cmd);
  msg.header.seq = ntohl(msg.header.seq);
  msg.header.body_size = ntohl(msg.header.body_size);

  msg.body.resize(msg.header.body_size);
  memcpy(msg.body.data(), data + sizeof(MessageHeader), msg.header.body_size);
  return msg;
}

// 消息处理线程
void message_processing_thread(int client_fd) {
  char buffer[4096];
  bool processing = true;

  while (processing) {
    // 读取消息头
    ssize_t bytes_read = recv(client_fd, buffer, sizeof(MessageHeader), 0);
    if (bytes_read <= 0) {
      std::cout << "Failed to read message header" << std::endl;
      break;
    }

    MessageHeader header;
    memcpy(&header, buffer, sizeof(MessageHeader));

    // 转换网络字节顺序到主机字节顺序
    header.magic = ntohs(header.magic);
    header.cmd = ntohs(header.cmd);
    header.seq = ntohl(header.seq);
    header.body_size = ntohl(header.body_size);

    std::cout << "Message header: magic=" << header.magic
              << ", cmd=" << header.cmd << ", seq=" << header.seq
              << ", body_size=" << header.body_size << std::endl;

    // 读取消息体
    if (header.body_size > 0) {
      bytes_read =
          recv(client_fd, buffer + sizeof(MessageHeader), header.body_size, 0);
      if (bytes_read <= 0) {
        std::cout << "Failed to read message body" << std::endl;
        break;
      }
    }

    // 解析消息
    Message msg;
    msg.header = header;
    msg.body.resize(header.body_size);
    memcpy(msg.body.data(), buffer + sizeof(MessageHeader), header.body_size);

    std::cout << "Message body: ";
    for (size_t i = 0; i < msg.body.size(); ++i) {
      std::cout << std::hex
                << static_cast<int>(static_cast<unsigned char>(msg.body[i]))
                << " ";
    }
    std::cout << std::dec << std::endl;

    // 处理消息并发送响应
    process_message(msg, client_fd);
  }

  close(client_fd);
  std::cout << "Client disconnected" << std::endl;
}

// TCP服务器线程
void tcp_server_thread(int port) {
  int server_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (server_fd < 0) {
    std::cerr << "Failed to create socket" << std::endl;
    return;
  }

  sockaddr_in server_addr;
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = INADDR_ANY;
  server_addr.sin_port = htons(port);

  if (bind(server_fd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
    std::cerr << "Failed to bind socket" << std::endl;
    close(server_fd);
    return;
  }

  if (listen(server_fd, 5) < 0) {
    std::cerr << "Failed to listen on socket" << std::endl;
    close(server_fd);
    return;
  }

  std::cout << "Server listening on port " << port << std::endl;

  while (true) {
    sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    int client_fd = accept(server_fd, (sockaddr *)&client_addr, &client_len);
    if (client_fd < 0) {
      std::cerr << "Failed to accept connection" << std::endl;
      continue;
    }

    std::cout << "Client connected: " << inet_ntoa(client_addr.sin_addr) << ":"
              << ntohs(client_addr.sin_port) << std::endl;

    // 启动消息处理线程
    std::thread processing_thread(message_processing_thread, client_fd);
    processing_thread.detach();
  }

  close(server_fd);
}

int main(int argc, char *argv[]) {
  if (argc != 2) {
    std::cerr << "Usage: " << argv[0] << " <port>" << std::endl;
    return 1;
  }

  //   int port = std::stoi(argv[1]);

  // 启动TCP服务器线程
  std::thread server_thread(tcp_server_thread, 10086);

  server_thread.join();

  return 0;
}